/*
 * Location.cpp
 *
 *  Created on: Dec 21, 2014
 *      Author: wasp
 */

#include "Location.hpp"
#include "Route.hpp"
#include <bb/platform/geo/GeoLocation>
#include <bb/platform/geo/Marker>
#include <bb/UIToolkitSupport>
#include <bb/cascades/maps/MapView>
#include <bb/cascades/maps/MapData>
#include <bb/cascades/maps/DataProvider>
#include <math.h>


using namespace bb::platform::geo;

namespace de
{
namespace heimweghelden
{
namespace location
{

    Location::Location(QObject* parent)
    : QObject(parent)
    {
        _route = NULL;
        followDevice = true;
        _current = new GeoLocation("device-location-current");
        // creating a data provider just for the device location object. that way, when the clear function is call, this object is not removed.
        _deviceLocationDataProvider = new bb::cascades::maps::DataProvider("device-location-data-provider");
        _deviceLocationDataProvider->add(_current);

        _map = NULL;

        Marker currenteye = Marker
        (
                bb::UIToolkitSupport::absolutePathFromUrl(QUrl("asset:///images/icons/ic_location_me.png")),
                QSize(96, 96),
                QPoint(48, 15),
                QPoint(48, 96)
        );
        _current->setMarker(currenteye);
        _current->setName(tr("Start"));
    }
    bb::platform::geo::GeoLocation* Location::current() {
        return _current;
    }
    void Location::centerMap() {
        if (_map) {
            _map->setLatitude(_current->latitude());
            _map->setLongitude(_current->longitude());
        }
    }
    void Location::setRoute(double lat, double lon, QString destcription) {
        followDevice = false;
        _route = new Route(this, _current->latitude(),_current->longitude(),  lat, lon);

        Marker destinationeye = Marker
        (
                bb::UIToolkitSupport::absolutePathFromUrl(QUrl("asset:///images/icons/ic_location_destination.png")),
                QSize(96, 96),
                QPoint(48, 80),
                QPoint(48, 1)
        );
        GeoLocation* end = new GeoLocation("device-location-end");
        end->setName(tr("Destination"));
        end->setDescription(destcription);
        end->setLatitude(lat);
        end->setLongitude(lon);
        end->setMarker(destinationeye);
        _deviceLocationDataProvider->add(end);


        // show all locations
        _map->setLocationOnVisible();
    }
    void Location::resetRoute() {
        followDevice = true;
        _deviceLocationDataProvider->remove("device-location-end");
        delete _route;
        _route = NULL;
    }
    bb::cascades::maps::MapView* Location::map() {
        return _map;
    }
    void Location::setMap(bb::cascades::maps::MapView* map) {
        if (_map == NULL) {
            _map = map;
            _map->setCaptionGoButtonVisible(false);
            _map->mapData()->addProvider(_deviceLocationDataProvider);
        }
    }
    void Location::updateDevice(double lat, double lon) {
        _current->setLatitude(lat);
        _current->setLongitude(lon);
        if (followDevice) {
            _map->setLatitude(lat);
            _map->setLongitude(lon);
        }
        if (_route != NULL) {
            _route->updatePosition(lat, lon);
        }
    }
    double toRadians(double inp) {
        return inp * (M_PI/180);
    }
    double Location::distance(double lat1, double lon1, double lat2, double lon2) {
        double R = 6371000; // erdradius in m
        double dlon = toRadians(lon2 - lon1);
        double dlat = toRadians(lat2 - lat1);

        double t = sin(dlat/2);
        t = t * t;
        double t2 = sin(dlon/2);
        t2 = t2 * t2;
        double a =
                t +
                cos(toRadians(lat1)) * cos(toRadians(lat2)) *
                t2;

        double c = 2 * atan2( sqrt(a), sqrt(1-a) );
        return R * c;
    }
    Route* Location::route() { return _route; }
    Location::~Location() {
        if (_route) {
            delete _route;
        }
        delete _current;
    }
} /* namespace location */
} /* namespace heimweghelden */
} /* namespace de */
